#include "HttpHandler.h"
#include <sstream>
#include <cassert>
#include "global.h"
#include "HttpData.h"
#include "HttpDecoder.h"


HttpHandler::HttpHandler(HttpHandlerSetting& handler_setting)
	:m_handler_setting(handler_setting)
{
	handler_id = 0;
	m_heat_beat_timer.Start(HTTP_HEART_BEATT_TIME_CHECK, this);
	m_keepalive_timer.Start(HTTP_KEEP_ALIVE_TIMEOUT_SEC * 1000, this);
	m_heat_beat_events = 0;
	m_keepalive_cnt = 0;
	m_keepalive_active = HTTP_KEEP_ALIVE_OPEN;
}

HttpHandler::~HttpHandler()
{
	m_heat_beat_timer.Stop();
	m_heat_beat_events = 0;

	if (HTTP_KEEP_ALIVE_OPEN) 
	{
	    m_keepalive_timer.Stop();
		m_keepalive_cnt = 0;
	}
	m_keepalive_active = HTTP_KEEP_ALIVE_OPEN;
}

int HttpHandler::Close()
{
	return OnClose();
}

int HttpHandler::Response(stHttpResponse&& response)
{
	std::stringstream ss;
	ss << "HTTP/1.1 " << response.state << " OK\r\nAccess-Control-Allow-Origin: *\r\n";
    if(response.heads.empty())
	{
        ss << "Content-Type: text/html; charset=utf-8\r\n";
    }
	else 
	{
		for(auto itHead = response.heads.begin(); itHead != response.heads.end() ;++itHead)
		{
			ss << itHead->first << ": " << itHead->second << "\r\n";
		}
	}
	ss << "Content-Length: " << response.body.size() << "\r\n\r\n";
	ss << std::move(response.body);

	int ret= CCSocketHandler::Send(ss.str().c_str(), ss.str().size());
	CheckResponseComplete();
	return ret;
}

void HttpHandler::CheckResponseComplete()
{
	if (HTTP_KEEP_ALIVE_OPEN)
	{
		m_keepalive_cnt++;
	
		// 检查keep-alive
		if (m_keepalive_active && (m_keepalive_cnt < HTTP_KEEP_ALIVE_MAX_TIMES))
		{
			m_keepalive_timer.Start(HTTP_KEEP_ALIVE_TIMEOUT_SEC * 1000, this);
			return;
		}
	}
	Close();
}

int HttpHandler::InputNotify()
{
	m_heat_beat_events++;
	if (HTTP_KEEP_ALIVE_OPEN) m_keepalive_timer.Stop();
	// 不要在 InputNotify 后面 再 调用成员函数和成员变量, InputNotify有逻辑会del this,会导致程序崩溃
	return CCSocketHandler::InputNotify();
}
int HttpHandler::OutputNotify()
{
	int ret = CCSocketHandler::OutputNotify();
	CheckResponseComplete();
	return ret;
}

int HttpHandler::HangupNotify()
{
	int ret = CCSocketHandler::HangupNotify();
	return ret;
}

int HttpHandler::ProcessOnTimerOut(int Timerid)
{
	switch (Timerid)
	{
	case HTTP_HEART_BEATT_TIME_ID:
		if (m_heat_beat_events > 0)
		{
		    m_heat_beat_timer.Start(HTTP_HEART_BEATT_TIME_CHECK, this);
			m_heat_beat_events = 0;
		}
		else
		{
			OnTimeout();
		}
		break;
	case HTTP_KEEP_ALIVE_TIME_ID:
		Close();
		break;
	default:
		break;
	}
	return 0;
}

int HttpHandler::OnConnected()
{
	int ret = m_handler_setting.on_connected(this);
	if (ret == 0)
	{
		m_heat_beat_timer.Start(HTTP_HEART_BEATT_TIME_CHECK, this);
		m_heat_beat_events = 0;
		if (HTTP_KEEP_ALIVE_OPEN)
		{
			m_keepalive_timer.Start(HTTP_KEEP_ALIVE_TIMEOUT_SEC * 1000, this);
			m_keepalive_cnt = 0;
		}
	}
	return ret;
}

int HttpHandler::OnClose() 
{
	return m_handler_setting.on_close(this);	
}

int HttpHandler::OnTimeout()
{
	m_handler_setting.on_timeout(this);
	return Close();
}

int HttpHandler::OnPacketComplete(const char * data, int len)
{
    HttpDecoder* http_decoder = dynamic_cast<HttpDecoder*>(this->decoder.get());
	assert(http_decoder != nullptr);
	if (HTTP_KEEP_ALIVE_OPEN)
	{
		// 默认开启keepalive
		m_keepalive_active = true;
		if (0 == CheckHeaderParam(http_decoder->m_cache.heads, "Connection", "close"))
		{
			// 指明则关闭
			m_keepalive_active = false;
		}
	}
	return m_handler_setting.on_message(this, std::move(http_decoder->m_cache));
}

ICC_Decoder* HttpHandler::CreateDecoder()
{
	return new HttpDecoder();
}

int HttpHandler::Init()
{
	CCSocketHandler::Init();
	return 0;
}


